///////////////////////////////
///     Made by Team AOF    ///
/// modified by gardenapple ///
///////////////////////////////

//////////////////////////////////////////////////
//   AOF Unification Script - MIT licensed.     //
//////////////////////////////////////////////////

const GENERATE_REI_SCRIPT = true

// List of part tags to unify.
const RESOURCE_TAG_TEMPLATES = [
	"c:{}_blocks",
	"c:{}_dusts",
	"c:{}_ingots",
	"c:{}_nuggets",
	"c:{}_plates",
	"c:raw_{}_ores",
	"c:raw_{}_blocks"
]
// List of materials to unify.
const RESOURCES = [
	"aluminum",
	"bauxite",
	"bronze",
	"chromium",
	"coal",
	"copper",
	"diamond",
	"electrum",
	"emerald",
	"gold",
	"invar",
	"iridium",
	"iron",
	"lapis",
	"lead",
	"manganese",
	"netherite",
	"nickel",
	"platinum",
	// "quartz",
	"ruby",
	"silicon",
	"silver",
	"steel",
	"sulfur",
	"tin",
	"titanium",
	"tungsten",
	"salt",
	"carbon",
	"brass",
	"zinc"
]
// Order of mods to unify
const RESOURCE_MOD_ORDER = [
	"minecraft",
	"create",
	"createplus",
	"sandwichable", //salt dust
	"bagels_baking", //salt dust
	"modern_industrialization",
	"mythicmetals",
	"smitheesfoundry",
	"amethyst_imbuement",
	"malum",
	"yttr",
	"ad_astra",
	"illagerexp",
]


// Same but for farming mods

const FARMING_TAGS = [
	"c:tomato",
	"c:tomato_seeds",
	"c:lettuce_head",
	"c:lettuce_seeds",
	"c:onion",
	"c:grapes",
	"c:flour",
	"c:fried_eggs",
	"ariadne:honeyed_apples"
]

const FARMING_MOD_ORDER = [
	"minecraft",
	"create",
	"farmersdelight",
	"culinaire",
	"bodacious_berries",
	"sandwichable",
	"bagels_baking",
	"additionaladditions"
]


// Map of removed item -> unified variant.
const itemIdToUnified = {}
// List of all unification tags.
const unifiedTagList = []

let errorDuringTagSearch = false

function findTagUnification(event, tagName, modOrder) {
	const tagItems = event.get(tagName).getObjectIds()

	// Check if unification is OK
	let doUnify = true
	// tagItems.forEach(id => {
	// 	// Don't unify if it contains the MC namespace
	// 	if (id.getNamespace() === "minecraft") {
	// 		doUnify = false
	// 	}
	// })
	// if (!doUnify) return

	let unifyTargetId = undefined
	modOrder.forEach(unificationNamespace => {
		// Do tag unification
		tagItems.forEach(id => {
			id = "" + id // convert ResLoc to native JS string

			const namespace = id.split(":")[0]
			// If a namespace is not in the order list, crash
			if (!modOrder.includes(namespace)) {
				console.log(`Missing namespace ${namespace} in the unification order: ${modOrder}. Required by item ${id} in tag ${tagName}.`)
				errorDuringTagSearch = true
			}
			// Otherwise pick the best in the list
			if (namespace === unificationNamespace) {
				if (unifyTargetId === undefined) {
					unifyTargetId = id
				}
			}
		})
	})

	if (unifyTargetId === undefined || doUnify === false) return undefined
	else return "" + unifyTargetId // Convert to string
}

function onChosenUnifyTarget(event, tagName, unifyTargetId) {
	if (unifyTargetId === undefined) return
	unifiedTagList.push(tagName)

	// Collect other items for item unification.
	event.get(tagName).getObjectIds().forEach(id => {
		id = "" + id // convert ResLoc to native JS string
		if (id in itemIdToUnified) {
			throw new Error("Item id " + id + " already has a unification mapping! " + itemIdToUnified[id])
		} else if (id !== unifyTargetId) {
			itemIdToUnified[id] = unifyTargetId
			// Remove from tag.
			event.remove(tagName, id)
		}
	})
}

// Unify common tags
onEvent('tags.items', event => {
	event.add("c:salt_dusts", ["#c:salt", "bagels_baking:salt"])
	for (const metal of ["tin", "silver", "platinum"])
		event.add(`c:raw_${metal}_ores`, `mythicmetals:raw_${metal}`)
	event.add("c:platinum_plates", "illagerexp:platinum_sheet")
	event.add("c:iron_dust", "yttr:iron_dust")
	//event.add("c:steel_blocks", "amethyst_imbuement:steel_block")
	//event.add("c:steel_ingots", "amethyst_imbuement:steel_ingot")

	event.add("c:brookite_ores", "yttr:brookite_ore")
	event.add("c:brookite_ores", "yttr:deepslate_brookite_ore")
	event.add("c:gadolinite_ores", "yttr:gadolinite")
	event.add("c:gadolinite_ores", "yttr:deepslate_gadolinite")
	for (const type of ["overworld", "nether", "end", "deepslate"]) {
		event.add("c:dragonstone_ores", `horde-resource-crops:ores/dragonstone_${type}_ore`)
		event.add("c:rhodonite_ores", `horde-resource-crops:ores/rhodonite_${type}_ore`)
	}
	for (const type of ["cobalt"]) {
		event.add(`c:${type}_ores`, `#c:ores/${type}`)
	}


	RESOURCES.forEach(material => {
		RESOURCE_TAG_TEMPLATES.forEach(partTagTemplate => {
			const tagName = partTagTemplate.replace("{}", material)

			const unifyTargetId = findTagUnification(event, tagName, RESOURCE_MOD_ORDER)
			onChosenUnifyTarget(event, tagName, unifyTargetId)
		})
	})

	event.add("c:tomato", ["culinaire:tomato", "bagels_baking:tomato", "#c:crops/tomato"])
	event.add("c:tomato_seeds", ["#c:seeds/tomato"])
	event.add("c:lettuce_head", ["culinaire:lettuce"])
	event.add("c:lettuce_seeds", ["culinaire:lettuce_seeds"])
	event.add("c:onion", ["#c:crops/onion", "bagels_baking:onion"])
	event.add("c:grapes", ["bagels_baking:grapes"])
	event.add("c:flour", ["bagels_baking:flour"])
	event.add("c:fried_eggs", [ "additionaladditions:fried_egg", "bagels_baking:cooked_egg"])
	event.add("ariadne:honeyed_apples", ["create:honeyed_apple", "additionaladditions:honeyed_apple"])

	FARMING_TAGS.forEach(tagName => {
		const unifyTargetId = findTagUnification(event, tagName, FARMING_MOD_ORDER)
		onChosenUnifyTarget(event, tagName, unifyTargetId)
	})



	if (errorDuringTagSearch)
		throw new Error("Got errors during tag search.")
})

onEvent('recipes', event => {
	// Replace inputs and outputs with unified items.
	for (let id in itemIdToUnified) {
		let unified = itemIdToUnified[id]
		console.log("Id: " + id + " to unified: " + unified)
		event.replaceInput({}, id, unified)
		event.replaceOutput({}, id, unified)
		event.shapeless(unified, id)
	}
	event.shapeless("bagels_baking:wild_rice", "farmersdelight:rice_panicle")

	if (GENERATE_REI_SCRIPT) {
		generateReiScript(itemIdToUnified)
	}
})

function generateReiScript(itemIdToUnified) {
	const script = `  
///////////////////////////////////////////////
//        AOF 5 REI Unification Script.      //
// auto-generated by server_scripts/unify.js //
///////////////////////////////////////////////
const DELETED_ITEMS = ["${Object.keys(itemIdToUnified).join('", "')}"]
onEvent("rei.hide.items", event => {
	DELETED_ITEMS.forEach(id => event.hide(id))
})
	`
	console.log("Generated REI unification script.")
	console.log(script)
}
